#include "Game.h"
#include <time.h>

Game::Game()
{
	then = clock();
	p1 = NULL;
	p2 = NULL;

	srand( clock() );

	/*
	p1 = new Player( XY(100,100) );
	p2 = new Player( XY(500,100) );
	asteroidVector->push_back(new Asteroid(XY(250,100), 6));
	*/
	asteroidVector = new std::vector<Asteroid*>;

//	asteroidVector->push_back(new Asteroid(XY(250,100), 6));

}

void Game::Open()
{
	p1 = new Player( XY(150,200) );
	p2 = new Player( XY(650,200) );
	//FIRST ASTEROID
	Asteroid* nAster = new Asteroid(XY(400,200), 9);
	nAster->asteroidVec = asteroidVector; //gotta set that asteroidVector for the asteroids to add themselves.
	nAster->Destroy();
	asteroidVector->push_back(nAster);
	//SECOND ASTEROID
	nAster = new Asteroid(XY(400,200), 9);
	nAster->asteroidVec = asteroidVector; //gotta set that asteroidVector for the asteroids to add themselves.
	nAster->Destroy();
	asteroidVector->push_back(nAster);
	//THIRD ASTEROID
	nAster = new Asteroid(XY(400,200), 9);
	nAster->asteroidVec = asteroidVector; //gotta set that asteroidVector for the asteroids to add themselves.
	nAster->Destroy();
	asteroidVector->push_back(nAster);

	gameOver = false;

}

void Game::Close()
{
	if(p1)
	{
		for(int i = p1->ownedBullets->size(); i > 0; --i)
		{
			p1->ownedBullets->pop_back();
		}
		delete p1;
	}
	if(p2)
	{
		for(int i = p2->ownedBullets->size(); i > 0; --i)
			p2->ownedBullets->pop_back();
		delete p2;
	}
	for(int i = asteroidVector->size(); i > 0; --i)
	{
		asteroidVector->pop_back();
	}

}


bool Game::GameOver()
{
	return gameOver;
}
/*

	time_t now, then, soon;
	float dt;
	Player* p1;
	Player* p2;

	std::vector<Asteroid*>* asteroidVector;
	//USE THE PLAYER'S BULLET VECTORS TO CHECK AGAINST ASTEROIDS AND PLAYERS.
		XY mousePos;
	bool mouseClicked;
	


	#define DIK_UP              0xC8    
	#define DIK_LEFT            0xCB   
	#define DIK_RIGHT           0xCD   
	#define DIK_DOWN            0xD0    
	#define DIK_SPACE           0x39   

	#define DIK_W               0x11
	#define DIK_A               0x1E
	#define DIK_S               0x1F
	#define DIK_D               0x20

bool keyBoard[KEYBOARD_BUFF_SIZE];
	*/

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

void Game::Update(InputStruct & isp1, InputStruct & isp2)
{
	now = clock();
	dt = (now - then) / 1000.0f; //delta time ms / 1000 ms/s
	then = now;

	//p1->aimAngle+=0.1;

	if(dt > 0.1) dt = 0.1f;

	if(isp1.keyBoard[DIK_UP] || isp1.keyBoard[DIK_W])
		p1->GoFast();
	if(isp1.keyBoard[DIK_DOWN] || isp1.keyBoard[DIK_S])
		p1->GoSlow();
	if(isp1.keyBoard[DIK_LEFT] || isp1.keyBoard[DIK_A])
		p1->RotateCounterclockwise(dt);
	if(isp1.keyBoard[DIK_RIGHT] || isp1.keyBoard[DIK_D])
		p1->RotateClockwise(dt);
	if(isp1.keyBoard[DIK_SPACE])
		p1->Shoot();

	if(isp2.keyBoard[DIK_UP] || isp2.keyBoard[DIK_W])
		p2->GoFast();
	if(isp2.keyBoard[DIK_DOWN] || isp2.keyBoard[DIK_S])
		p2->GoSlow();
	if(isp2.keyBoard[DIK_LEFT] || isp2.keyBoard[DIK_A])
		p2->RotateCounterclockwise(dt);
	if(isp2.keyBoard[DIK_RIGHT] || isp2.keyBoard[DIK_D])
		p2->RotateClockwise(dt);
	if(isp2.keyBoard[DIK_SPACE])
		p2->Shoot();

	

	p1->Update(dt);
	p2->Update(dt);
	for(int i = 0; i < asteroidVector->size() ; i++)
	{
		asteroidVector->at(i)->Update(dt);
	}
	for(int i = 0; i < p1->ownedBullets->size(); i++)
	{
		p1->ownedBullets->at(i)->Update(dt);
	}
	for(int i = 0; i < p2->ownedBullets->size(); i++)
	{
		p2->ownedBullets->at(i)->Update(dt);
	}

	HandleCollisions();

	CullDeadAsteroidsAndBullets();
}

void Game::PushIntoDrawStruct(LostVector<DrawStruct>* drawVec)
{
	//assuming it is already empty;
	DrawStruct background(0.0f, 0.5f, GAME_BACKGROUND, 0.0f);
	background.DrawFromCenter = false;
	drawVec->add(background);
	drawVec->add(DrawStruct(p1->GetPos(), 1, PLAYER, (180.0f * p1->aimAngle / PI) +90.0f ) );
	drawVec->add(DrawStruct(p2->GetPos(), 1, PLAYER, (180.0f * p2->aimAngle / PI) +90.0f ) );
	
	for(int i = 0; i < p1->ownedBullets->size(); ++i)
	{
		drawVec->add(DrawStruct(p1->ownedBullets->at(i)->GetPos(), 1, BULLET, 0) );
	}

	for(int i = 0; i < p2->ownedBullets->size(); ++i)
	{
		drawVec->add(DrawStruct(p2->ownedBullets->at(i)->GetPos(), 1, BULLET, 0) );
	}

	for(int i = 0; i < asteroidVector->size(); ++i)
	{
		drawVec->add(DrawStruct(asteroidVector->at(i)->GetPos(), (float)asteroidVector->at(i)->GetSize(), ENEMY, 0.0f) );
	}

}

void Game::HandleCollisions()
{
	for(int i = 0; i < asteroidVector->size() ; i++)
	{
		Asteroid* tmp = asteroidVector->at(i);
		if(SphericalCollision(p1->GetPos(), PLAYER_OFFSET, tmp->GetPos(), tmp->GetSize() * ASTEROID_OFFSET))
		{
			p1->Kill();
			gameOver = true;
		}
		if(SphericalCollision(p2->GetPos(), PLAYER_OFFSET, tmp->GetPos(), tmp->GetSize() * ASTEROID_OFFSET))
		{
			p2->Kill();
			gameOver = true;
		}/////////////////////////////////////////////////////////Player check against asteroids
		for(int i = 0; i < p1->ownedBullets->size(); i++)  ///check player 1's bullets against asteroids and against other player
		{
			if(SphericalCollision(tmp->GetPos(), tmp->GetSize() * ASTEROID_OFFSET, p1->ownedBullets->at(i)->GetPos(), BULLET_OFFSET))
			{
				tmp->Destroy();
				p1->ownedBullets->at(i)->Die();
			}

		}
		for(int i = 0; i < p2->ownedBullets->size(); i++)
		{
			if(SphericalCollision(tmp->GetPos(), tmp->GetSize() * ASTEROID_OFFSET, p2->ownedBullets->at(i)->GetPos(), BULLET_OFFSET))
			{
				tmp->Destroy();
				p2->ownedBullets->at(i)->Die();
			}
		}
	}

	for(int i = 0; i < p1->ownedBullets->size(); i++)  /////CHECK IF PLAYER GOT SNUFFED
		if(SphericalCollision(p2->GetPos(), PLAYER_OFFSET, p1->ownedBullets->at(i)->GetPos(), BULLET_OFFSET))
		{
			p2->TakeHit();
			p1->ownedBullets->at(i)->Die();
			if(p2->GetHealth() <= 0) gameOver = true;
		}

	for(int i = 0; i < p2->ownedBullets->size(); i++)/////CHECK IF PLAYER GOT SNUFFED
		if(SphericalCollision(p1->GetPos(), PLAYER_OFFSET, p2->ownedBullets->at(i)->GetPos(), BULLET_OFFSET))
		{
			p1->TakeHit();
			p2->ownedBullets->at(i)->Die();
			if(p1->GetHealth() <= 0) gameOver = true;
		}

	

}

void Game::HandleInput() //
{
	

}

void Game::CullDeadAsteroidsAndBullets()
{
	/////////////////////cull asteroids///////////
	for(int i = asteroidVector->size() -1  ; i >= 0 ; --i)
	{
		if(asteroidVector->at(i)->IsDead())
		{
			Asteroid* tmp = asteroidVector->at(i);
			asteroidVector->at(i) = asteroidVector->back();//delete asteroidVector->at(i);
			asteroidVector->back() = tmp;
			asteroidVector->pop_back();
			i--;
		}
	}
	//////////////////////////cull bullets////////////
	for(int i = p1->ownedBullets->size()-1; i >= 0 ; --i)
	{
		if(p1->ownedBullets->at(i)->IsDead())
		{
			Bullet* tmp = p1->ownedBullets->at(i);
			p1->ownedBullets->at(i) = p1->ownedBullets->back();//delete asteroidVector->at(i);
			p1->ownedBullets->back() = tmp;
			p1->ownedBullets->pop_back();
			
		}
	}

	for(int i = p2->ownedBullets->size()-1; i >= 0 ; --i)
	{
		if(p2->ownedBullets->at(i)->IsDead())
		{
			Bullet* tmp = p2->ownedBullets->at(i);
			p2->ownedBullets->at(i) = p2->ownedBullets->back();//delete asteroidVector->at(i);
			p2->ownedBullets->back() = tmp;
			p2->ownedBullets->pop_back();
			i--;
		}
	}



}
bool Game::SphericalCollision(XY apos, float aradius, XY bpos, float bradius) //tests collision between two spheres given their centers and radii
{
	float distBetween = sqrt( (apos.x - bpos.x) * (apos.x - bpos.x) + (apos.y - bpos.y) * (apos.y - bpos.y) );
	float totaledRadius = aradius + bradius;
	if(distBetween - totaledRadius <= 0)
		return true;
	return false;
}

Game::~Game()
{
	Close();
	delete asteroidVector;
}